#include "common.h"
#include "drv_fpga.h"
unsigned int * mmap_addr = NULL;  //这里代表内存的物理地址, 可以是其内核申请获得的物理地址,也可以是用户态申请获得的物理地址
#define MMAP_SIZE   16
extern int scan_type;
void AXI_init() {
    int fd = open("/dev/mem", O_RDWR);   /* 读写权限，非阻塞 */
    mmap_addr=(unsigned int *)mmap(NULL, MMAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x40000000);
    LOG_DEBUG("AXI mmap addr 0x%08x", mmap_addr);
    if(mmap_addr == NULL || mmap_addr == (void *)-1) {
        LOG_ERROR("AXI mmap init fail!");
#if     !MODULE_TEST
        exit(-1);
#endif
    }
    LOG_DEBUG("AXI init successful!");
}


void AXI_free() {
    if(mmap_addr == NULL || mmap_addr == (void *)-1) {
        LOG_ERROR("AXI mmap_addr is NULL");
        return;
    }
    if(!munmap(mmap_addr, MMAP_SIZE)) {
        LOG_INFO("AXI free sources successful");
    } else {
        LOG_ERROR("AXI free failed, errmsg: %s", strerror(errno));
    }
}

/**
 * 关于 GPIO 控制信号定义
 * addr :   val    
 * 
 * read
 * 
 * 0    :   read 发送SPI数据状态, 0: 可以发送数据, 1: 等待发送数据
 * 1    :   read 发送电源状态信息 
 * 2    :   read 发送检波信息
 * 3    :   read 发送温度信息
 * 4    :   read 接收电源信息
 * 5    :   read 接收温度信息
 * 
 * write
 * 
 * 0    :   write SPI数据发送地址
 * 5    :   write 电源控制, 0: 关闭, 1: 打开
 * 6    :   write 发送控制, 0: 关闭, 1: 关闭
 * 7    :   write 低16位为角度信息, --[光口]
 * 8    :   write 配置模式 [0]:70MHz  [1]:28MHz  [2]:14MHz --[光口]
 * 10   :   write 控制差分线 1 的脉冲信号, 扇区1, 1: 开始给一个脉冲信号 500us, 不发包头
 * 11   :   write 控制差分线 2 的脉冲信号, 扇区2, 1: 开始给一个脉冲信号 500us, 不发包头
 * 12   :   write 控制差分线 3 的脉冲信号, 扇区3, 1: 开始给一个脉冲信号 500us, 不发包头
 * 13   :   write 控制差分线 4 的脉冲信号, 步进 , 1: 开始给一个脉冲信号 500us, 不发包头
 * 
*/

/* 给定某个地址的脉冲信号 */
void set_pulse(int addr) {
#if !MODULE_TEST
    // send_data(0x5A5A55AA, addr);
    send_data(1, addr);
#else
    // LOG_INFO("addr: %d", addr);
#endif
}

#if !MODULE_TEST
void AXI_Test(int val, int addr) {
    LOG_INFO("AXI Test val: %d, addr: %d", val, addr);
    send_data(0x5A5A55AA, addr);
    send_data(val, addr);
}

void AXIC_Test(int val, int addr) {
    LOG_INFO("AXI Test val: %d, addr: %d", val, addr);
    // send_data(0x5A5A55AA, addr);
    send_data(val, addr);
}
#endif

void set_init_io() {
    send_data(0x5A5A55AA, 5);   //电源默认高
    send_data(1, 5);

    send_data(0x5A5A55AA, 6);   //发射控制默认开
    send_data(1, 6);
}

void Send_Ctr(int val) {
    send_data(0x5A5A55AA, 6);   //发射控制默认开
    send_data(val, 6);
}

/* 风扇控制 */
void ConTrolFanFun(uint8 *cbuf) {
    // 0x00为停止，0x01为25%满速转，0x02为50%满速转，
    // 0x03为75%满速转，0x04为100%满速转
    
}

/*  电源控制 */
void Power_TxCtr(uint8 *cbuf) {
    uint8 val = cbuf[2];
    LOG_INFO("Ctr power, ctr val: %d", val);
    send_data(0x5A5A55AA, 5);   //电源默认高
    send_data(val, 5);
}

/* 角度控制 [光口传输] */
void send_angle(double val) {
    int temp = (int)(val * 100);
    send_data(0x5A5A55AA, 7);
    send_data(temp & 0x00FF, 7);
}
/* 模式设置  [0]:70MHz  [1]:28MHz  [2]:14MHz --[光口] */
void send_model(int val) {
    send_data(0x5A5A55AA, 8);
    send_data(val, 8);
}

int read_data(int addr) {
    return (int)(mmap_addr[addr]);
}

void send_data(int ch, int addr) {
#if !MODULE_TEST  
    mmap_addr[addr] = ch;
#endif
}

extern int scan_flag;
void send_TRX(uint32 * buff, int size) {
    Step_pulse;
    int cnt = 0;
    // 先发送 TRx 组件
    // printf("\n");
    // for(cnt = 0; cnt < size; cnt++) {
    //     // buff[cnt] = cnt;
    //     if(cnt%8 == 0) {
    //         printf("\n");
    //     }
    //     int temp = htonl(buff[cnt]);
    //     printf("%08x ", temp);
    // }
    // printf("\n");
    
    if(scan_type == Test_Verify) {
        uint8 *ptr = (uint8 *) buff;
        int offset = 0;
        printf("Tx:");
        for(cnt = 0; cnt < size *2; cnt++) {
            if(cnt % 16 == 0) {
                printf("\n channel:%02d %2d~%d: ", offset + 1, offset*8 + 1, offset*8 + 8);
                offset++;
            }
            printf("%02x ", ptr[cnt]);
        }
        printf("\n");

        ptr = &ptr[16*16];
        printf("Rx:");
        offset = 0;
        for(cnt = 0; cnt < size *2; cnt++) {
            if(cnt % 16 == 0) {
                printf("\n channel:%02d %d~%d: ", offset + 1, offset*8 + 1, offset*8 + 8);
                offset++;
            }
            printf("%02x ", ptr[cnt]);
        }
        printf("\n");
    }
#if !MODULE_TEST
    send_data(0x5A5A55AA, 0);
    for(cnt = 0; cnt < size; cnt++) {
        send_data(htonl(buff[cnt]), 0);
    }
    if(scan_type == Scan_Circle || scan_type == Scan_Fanshaped) {
        while(read_data(0) != 0x01) {
            if(scan_flag == END___SCAN) {
                break;
            }
            // LOG_DEBUG("====> temp %d", temp);
            // sleep(1);
        };
    }
#else 
    usleep(1000*10);
#endif // MODULE_TEST
    
}

void send_net_data(uint8 *cbuf, int clen);
void sendStatusTR(int type) {
    //TR 组件上报查询
    StatusTRData sTRdata;
    sTRdata.head = 0xBB;
    sTRdata.flag = 0x05;
    // 1 正常， 0 异常
    sTRdata.R_Temperature = read_data(5); //接收温度信息
    sTRdata.R_Power = read_data(4); //接收电源信息
    sTRdata.T_Temperature = read_data(3); //发送温度信息
    sTRdata.T_Detection = read_data(2); //发射T合成网络检波为1正常，0异常
    sTRdata.T_Power = read_data(1); //发送电源
    sTRdata.Check = ~0x05;
    sTRdata.end = 0xEE;

    if(type == 1) {
        LOG_INFO("R_Temperature-> %04x, R_Power-> %04x, T_Temperature-> %04x, T_Power-> %04x, T_Detection-> %04x ", \
                sTRdata.R_Temperature, sTRdata.R_Power, sTRdata.T_Temperature, sTRdata.T_Power, sTRdata.T_Detection);
        send_net_data((unsigned char *)&sTRdata, sizeof(sTRdata));
    }

    if(type == 2) {
        if(sTRdata.R_Temperature != 0xFFFF \
        || sTRdata.R_Power != 0xFFFF \
        || sTRdata.T_Temperature != 0xFFFF \
        || sTRdata.T_Detection != 0xFFFF \
        || sTRdata.T_Power != 0xFFFF ) {
            send_net_data((unsigned char *)&sTRdata, sizeof(sTRdata));
        }
    }


}

void * sendStatusTR_thread() {
    while(1) {
        sendStatusTR(2);
        usleep(500*1000);
    }
}

void upload_status() {
    pthread_t upload_thread_id;
    pthread_create(&upload_thread_id, NULL, sendStatusTR_thread, NULL);
}
